home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / util / libs / graphics3d.lha / src / library / graphics3D2d.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-16  |  15.9 KB  |  667 lines

  1. /*
  2. **      $VER: graphics3D2d.c 11.00 (10.05.98)
  3. **
  4. **      External functions for graphics3D.library
  5. **    In questa versione eventuali attivazioni di
  6. **    Goraud shading o ZBuffering vengono semplicemente
  7. **    ignorate.
  8. **    
  9. **      (C) Copyright 97 Patrizio Biancalani
  10. **      All Rights Reserved.
  11. */
  12.  
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <proto/exec.h>
  16. #include <proto/intuition.h>
  17. #include <intuition/intuition.h>
  18. #include <intuition/screens.h>
  19.  
  20. #include <graphics/rastport.h>
  21. #include <graphics/clip.h>
  22. #include <graphics/regions.h>
  23. #include <graphics/gfx.h>
  24. #include <graphics/gfxmacros.h>
  25. #include <graphics/layers.h>
  26.  
  27. #include "graphics3Dc.h"
  28. #include "graphics3D.h"
  29. #include "graphics3D2d_proto.h"
  30.  
  31.  /* Please note, that &Graphics3DBase always resides in register __a6 
  32.     as well, but if we don't need it, we need not reference it here.
  33.  
  34.     Also note, that registers a0, a1, d0, d1 always are scratch registers,
  35.     so you usually should only *pass* parameters there, but make a copy
  36.     directly after entering the function. To avoid problems of kind
  37.     "implementation defined behaviour", you should make a copy of A6 too,
  38.     when it is actually used.
  39.  
  40.     In this example case, scratch register saving would not have been 
  41.     necessary (since there are no other function calls inbetween), but we 
  42.     did it nevertheless.
  43.   */
  44.  
  45. /************ prototipi solo locali ******/
  46. struct RastPort *InitNBuff(struct grafica *graf);
  47.  
  48. void FreeNBuff(struct grafica *graf);
  49.  
  50. /**********************************************************/
  51.  
  52. /************ macro solo locali ******/
  53. #define DIPIU 500 
  54. #define PREC 8
  55. /*************************************/
  56.  
  57. /****************************************************
  58.  ** Routin per la gestione della grafica, in stile **
  59.  ** 2.0                                            ** 
  60.  ** (c) 1994 BIANCA HARD&SOFT Vers:1.00            **
  61.  ****************************************************/
  62.  
  63. /********* FUNZIONI 2D ********************************/
  64.  
  65. /***********************************
  66.  ** INIZIALIZZO STRUTTURE PER USO **
  67.  ** CON ROUTIN DI AREA FILL       **
  68.  ***********************************
  69.  **** INPUT :              **
  70.  ** win -> puntatore a finestra   **
  71.  **        su cui lavorare.       **
  72.  ** mxv -> n# massimo vertici da  **
  73.  **        usare.          **
  74.  **** OUTPUT :                    **
  75.  ** ris >0  - tutto ok.           **
  76.  ** ris =<0 - errore, ini.fallita.**
  77.  ***********************************/
  78. struct grafica *ini_g(struct Window *win,long int mxv,long int dx,long int dy)
  79. {
  80. struct grafica *ris;
  81. struct Screen *scr;
  82. struct RastPort *rw;
  83. struct RastPort *r;
  84. struct Layer *la;
  85. long int i,x,y;
  86.  
  87. ris=(struct grafica *)AllocMem(sizeof(Sgrafica),NULL);
  88. if (ris==NULL) return (0);
  89.  
  90. ris->vpor=0;
  91. ris->rast=0;
  92. ris->rast1=0;
  93. ris->rast2=0;
  94. ris->fdouble=1;
  95. ris->b_af=0;
  96. ris->pras=0;
  97. x=dx;
  98. y=dy;
  99. if (x>MAXDX) x=MAXDX;
  100. if (y>MAXDY) y=MAXDY;
  101.  
  102. /** default si single buffer **/
  103. ris->clipx=0;
  104. ris->clipy=0;
  105. i=((x+15)/16)*16;
  106. ris->clipdx=i;
  107. ris->clipdy=y;
  108. ris->zbuf=0;
  109. ris->dbuf=0;
  110. ris->ldbuf=0;
  111. ris->tmp_rp.BitMap=0;
  112. ris->NB_rinfo=0;       
  113. ris->NB_bmap=0;        
  114. ris->NB_layerinfo=0;   
  115. ris->NB_layer=0;       
  116.  
  117. rw=win->RPort;
  118. scr=win->WScreen;
  119. ris->vpor=&(scr->ViewPort);
  120. la=win->WLayer;
  121. ris->wind=win;
  122. ris->larg=LTMP;
  123. ris->alte=ATMP;
  124.  
  125. ris->depth=1<<(rw->BitMap->Depth);
  126. ris->r_color=4;                /* n# colori da non usare nella gen. palette */
  127. ris->n_level=ris->depth - ris->r_color;    /* n# livelli intensita' per ogni colore */
  128. ris->n_color=1;                /* n# colori base nella palette */
  129.  
  130. i=(long int)AllocMem(LEN_TABC,NULL);    /* alloco memoria per tabella colori base */
  131. if (i==NULL)
  132.     {
  133.     close_g(ris);
  134.     return(0);
  135.     }    
  136. ris->t_color=(long int *)i;
  137.  
  138. /* non alloco la memoria per la tabella delle texture map */
  139. ris->a_tmap=0;
  140.  
  141. r=InitNBuff(ris);
  142. if ((long int)r==NULL) {
  143.     close_g(ris);
  144.     return(0);
  145.     }
  146. ris->rast1=rw;
  147. ris->rast2=r;
  148. ris->rast=r;
  149. ris->o_ai=r->AreaInfo;
  150. ris->o_tr=r->TmpRas;
  151.  
  152. /* se per buffer richiesto meno di 1 vertice e' meglio evitare */
  153. if (mxv<=1) {
  154.     close_g(ris);
  155.     return(0);
  156.     }
  157. /* faccio in modo di allineare alle words la dimensione dell'area */
  158. i=mxv;
  159. if (((mxv>>1)<<1)!=mxv) i++;
  160. ris->b_af=AllocMem(MAXVER(i),NULL);
  161. if (ris->b_af==NULL) {
  162.     close_g(ris);
  163.     return(0);    
  164.     }
  165. ris->lb_af=i;
  166.  
  167. InitArea(&ris->n_ai,ris->b_af,mxv);
  168. r->AreaInfo=&ris->n_ai;
  169.  
  170. ris->pras=(char *)AllocRaster(ris->larg,ris->alte);
  171. if (ris->pras==NULL) {
  172.     close_g(ris);
  173.     return (0);
  174.     }
  175.  
  176. InitTmpRas(&ris->n_tr,ris->pras,RASSIZE(ris->larg,ris->alte));
  177.  
  178. r->TmpRas=&ris->n_tr;
  179.  
  180. return(ris);
  181. }
  182.  
  183. /***********************************
  184.  ** NON FA NULLA SOLO PER POTER   **
  185.  ** USARE GLI STESSI MODULI DELLA **
  186.  ** VERSIONE OTTIMIZZATA.      **
  187.  ***********************************
  188.  **** INPUT :              **
  189.  ** Ignorato              **
  190.  ***********************************/
  191. long int c_zbuf(struct ambient3d *in)
  192. {
  193. return(0);
  194. }
  195.  
  196. /***********************************
  197.  ** CHIUDO TUTTE LE STRUTTURE     **
  198.  ** APERTE CON LA FUNZIONE PRECE- **
  199.  ** DENTE.                        **
  200.  ***********************************
  201.  **** INPUT :                     **
  202.  ** graf -> valore >0 ritornato   **
  203.  **         dalla funzione d'ini- **
  204.  **         zializzazione         **
  205.  ***********************************/
  206. void close_g(struct grafica *graf)
  207. {
  208. struct RastPort *r;
  209. struct Layer *la;
  210. long int c;
  211.  
  212. if ((long int)graf != NULL)
  213.     {
  214.     la=graf->wind->WLayer;
  215.     if (graf->fdouble!=NULL) la=graf->NB_layer;
  216.     if (la->ClipRegion!=NULL)
  217.         {
  218.         c=InstallClipRegion(la,NULL);
  219.         DisposeRegion(c);
  220.         }
  221.     r=graf->rast;
  222.     if ((long int)r > NULL )
  223.         {
  224.         r->AreaInfo=graf->o_ai;
  225.         r->TmpRas=graf->o_tr;
  226.         }
  227.     if (graf->b_af!=NULL) FreeMem(graf->b_af,MAXVER(graf->lb_af));
  228.     if (graf->pras!=NULL) FreeRaster(graf->pras,graf->larg,graf->alte);
  229.     if (graf->fdouble!=NULL) FreeNBuff(graf);
  230.     FreeMem(graf,sizeof(Sgrafica));
  231.     }
  232. }
  233.  
  234. /************************************
  235.  ** FUNZIONE PER VISUALIZZARE LA   **
  236.  ** RASTPORT NASCOSTA SULLA        **
  237.  ** FINESTRA.               **
  238.  ************************************
  239.  **** INPUT :               **
  240.  ** graf -> valore >0 ritornato    **
  241.  **         dalla funzione d'ini-  **
  242.  **         zializzazione.         **
  243.  **** OUTPUT:               **
  244.  ************************************/
  245. void switch_rp(graf)
  246. struct grafica *graf;
  247. {
  248.  
  249. /** se libreria non ottimizzata **/
  250. ClipBlit(graf->rast2,0,0,graf->rast1,graf->clipx,
  251.     graf->clipy,graf->clipdx,graf->clipdy,0xc0);
  252. WaitBlit();
  253.  
  254. }
  255.  
  256. /************************************
  257.  ** FUNZIONE PER DEFINIRE UN BOX   **
  258.  ** DI CLIP SULLA FINESTRA         **
  259.  ************************************
  260.  **** INPUT :               **
  261.  ** graf -> valore >0 ritornato    **
  262.  **         dalla funzione d'ini-  **
  263.  **         zializzazione.         **
  264.  ** minx - valore minimo x box.    **
  265.  ** miny - valore minimo y box.    **
  266.  ** dx - larghezza box.           **
  267.  ** dy - altezza box.           **
  268.  **** OUTPUT:               **
  269.  ** > 0 tutto ok, valore effettivo **
  270.  **     larghezza box in pixel.    ** 
  271.  ** = 0 errore.               **
  272.  **** NOTA:               **
  273.  ** elimina eventuali clip region  **
  274.  ** preesistenti.              **
  275.  ** Se dx o dy =0 allora ritorna   **
  276.  ** valore effettivo di dx.        **
  277.  ** dy max =2999.           **
  278.  ** dx max =2999.           **
  279.  ************************************/
  280. long int clipbox(struct grafica *graf,long int minx,
  281.            long int miny,long int dx,long int dy)
  282. {
  283. struct Layer *la;
  284. struct Region *clipr;
  285. struct Rectangle rect;
  286. struct ClipRect *clrt;
  287. long int esi;
  288. long int i,x,y;
  289.  
  290. #ifdef DEBUG
  291. char dbg[80];
  292. #endif
  293.  
  294. if (dx==0 OR dy==0) return(graf->clipdx);
  295.  
  296. x=dx;
  297. y=dy;
  298.  
  299. if (y>MAXDY) y=MAXDY;
  300. if (x>MAXDX) x=MAXDX;
  301.  
  302.  
  303. i=((x+15)/16)*16;
  304.  
  305. graf->clipx=minx;
  306. graf->clipy=miny;
  307.  
  308. #ifdef DEBUG
  309. sprintf(dbg,"mx=%ld my=%ld dx=%ld dy=%ld \n",minx,miny,dx,dy);
  310. write_dbg(dbg);
  311. #endif
  312.  
  313. graf->clipdx=i;
  314. graf->clipdy=y;
  315.  
  316. la=graf->wind->WLayer;
  317. if (graf->fdouble) la=graf->NB_layer;
  318.  
  319. /*
  320. if (minx==0 AND miny==0 AND dx==0 AND dy==0)
  321.     {
  322.     if (graf->fdouble)
  323.         {
  324.         }
  325.     else
  326.         {
  327.         clipr=(struct Region *)InstallClipRegion(la,NULL);
  328.         if (clipr) DisposeRegion(clipr);
  329.         return (0);
  330.         }
  331.     }
  332. if (graf->fdouble==NULL)
  333.     {
  334.     wn=graf->wind;
  335.     la=wn->WLayer;
  336.     }
  337. */
  338.  
  339. /** elimino eventuali clipregion preesistenti **/
  340. clipr=(struct Region *)InstallClipRegion(la,NULL);
  341. if (clipr) DisposeRegion(clipr);
  342.  
  343. /** inizializzo una nuova clip region vuota **/
  344. clipr=(struct Region *)NewRegion();
  345. if (clipr==NULL) return (0);
  346.  
  347. rect.MinX=0;
  348. rect.MinY=0;
  349. if(graf->fdouble==NULL) 
  350.     {
  351.     rect.MinX=graf->clipx;
  352.     rect.MinY=graf->clipy;
  353.     }
  354. rect.MaxX=graf->clipdx;
  355. rect.MaxY=graf->clipdy;
  356.  
  357. OrRectRegion(clipr,&rect);
  358. InstallClipRegion(la,clipr);
  359.  
  360. return (graf->clipdx);
  361. }
  362.  
  363. /*************************************
  364.  ** FUNZIONE PER CANCELLARE UN BOX  **
  365.  ** NELLA FINESTRA .            **
  366.  *************************************
  367.  **** INPUT :                       **
  368.  ** graf -> valore >0 ritornato da  **
  369.  **         ini_g().                **
  370.  ** x0   -> coord. x punto in alto  **
  371.  **         a sinistra box.         **
  372.  ** y0   -> coord. y punto in alto  **
  373.  **         a sinistra box.         **
  374.  ** x1   -> coord. x punto in basso **
  375.  **         a destra box.        **
  376.  ** y1   -> coord. y punto in basso **
  377.  **        a destra box.        **
  378.  **** NOTA :                **
  379.  ** usa il colore dello sfondo, e   **
  380.  ** non influenza le altre funzioni **
  381.  *************************************/
  382. void cls_b(struct grafica *graf,long int x0,
  383.     long int y0,long int x1,long int y1)
  384. {
  385. long int i;
  386. char c,*db;
  387. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  388.  
  389. /* se uso libreria non ottimizzata */
  390. EraseRect(graf->rast,x0,y0,x1,y1);
  391. }
  392.  
  393. /*************************************
  394.  ** FUNZIONE PER CAMBIARE IL MODO   **
  395.  ** VIDEO DI TRACCIAMENTO.          **
  396.  *************************************
  397.  **** INPUT :                       **
  398.  ** graf -> valore >0 ritornato da  **
  399.  **         ini_g().                **
  400.  ** mod  -> nuovo modo video.       **
  401.  **** NOTA :                **
  402.  ** valori per mod :            **
  403.  ** 0 > JAM1 (over 2)            **
  404.  ** 1 > JAM2 (over 0) (def.)        **
  405.  ** 2 > COMPLEMENT (over 1)         **
  406.  ** 4 > INVERSVID  (inverse 1)      **
  407.  *************************************/
  408. void over(struct grafica *graf,long int mod)
  409. {
  410. if (((long int)graf<=NULL) OR ((long int)(graf->rast)<=NULL)) return(0); 
  411.  
  412. SetDrMd(graf->rast,mod);
  413. }
  414.  
  415. /********* ROUTIN INTERNE PER PSEUDO DOUBLE BUFFERING ***************/
  416. /*********************************************
  417.  ** INIZIALIZZO NUOVA RASTPORT PER USARLA   **
  418.  ** COME AREA DI RENDERING NASCOSTA.        **
  419.  *********************************************
  420.  **** INPUT :                    **
  421.  **** OUTPUT:                    **
  422.  ** se > 0 allora puntatore a nuova rastport**
  423.  *********************************************
  424.  ** nota: inizializzo una bitmap uguale     **
  425.  ** alla finestra usata per visualizzare la **
  426.  ** scena effettivamente.                **
  427.  *********************************************/
  428. struct RastPort *InitNBuff(struct grafica *graf)
  429. {
  430. struct RastPort *rport = NULL;  
  431. struct Window *win;
  432. struct Screen *screen;
  433. short int err = NULL;
  434. unsigned char depth;
  435. long int i;
  436. #ifdef DEBUG
  437. char dbg[100];
  438. #endif
  439.  
  440. win=graf->wind;
  441. screen=win->WScreen;
  442. depth=screen->BitMap.Depth;
  443.  
  444. graf->tmp_rp.BitMap=NULL;
  445. graf->dbuf=NULL;
  446.  
  447. /** 
  448.    Uso routin non ottimizzate passo da una rastport con display buffer nascosto
  449.    di tipo planar per usare il blitter
  450. **/
  451. if (!(graf->NB_layerinfo = (struct Layer_Info *)NewLayerInfo())) 
  452.     return (NULL);
  453.  
  454. if (!(graf->NB_bmap =(struct BitMap *)AllocBitMap(win->Width+SMARG,
  455.     win->Height+SMARG,depth,BMF_CLEAR|BMF_DISPLAYABLE,
  456.     graf->rast1->BitMap))) {
  457.    err = 3;
  458.    goto NBInit_done;
  459.    }
  460.  
  461. if (!(graf->NB_layer = (struct Layer *)CreateBehindLayer(graf->NB_layerinfo,
  462.         graf->NB_bmap,SMARGM,SMARGM, win->Width-1, win->Height-1,
  463.         LAYERSIMPLE|LAYERBACKDROP, NULL))) {
  464.    err = 4;
  465.    goto NBInit_done;
  466.    }
  467. rport = graf->NB_layer->rp;
  468.  
  469. SetRast(rport, 0);   
  470.  
  471. NBInit_done:
  472. if (err) FreeNBuff(graf);
  473. return (rport);
  474. }
  475.  
  476. /***************************************************
  477.  ** CHIUDO TUTTE LE AREE APERTE DALLA InitNBuff() **
  478.  ***************************************************/
  479. void FreeNBuff(struct grafica *graf)
  480. {
  481. unsigned char depth;
  482. struct RastPort *rp;
  483.  
  484. rp=graf->rast2;
  485. if (graf->NB_layer) DeleteLayer(0L, graf->NB_layer);
  486. if (graf->NB_layerinfo) DisposeLayerInfo(graf->NB_layerinfo);
  487.  
  488. if (graf->NB_bmap) 
  489.     {
  490.     WaitBlit();
  491.     FreeBitMap(graf->NB_bmap);  
  492.     }
  493. }
  494.  
  495. /********* FUNZIONI 2D NON OTTIMIZZATE ********************************/
  496.  
  497. /***********************************
  498.  ** RIEMPIO IL DISPLAY FILE COL   **
  499.  ** COLORE DELLO SFONDO.      **
  500.  ***********************************
  501.  **** INPUT :              **
  502.  ** amb3d -> valore >0 ritornato  **
  503.  **         dalla funzione d'ini- **
  504.  **         zializzazione.        **
  505.  **** OUTPUT:              **
  506.  ** nessuno .              **
  507.  ***********************************/
  508. void cls_f(amb3d)
  509. struct ambient3d *amb3d;
  510. {
  511.  
  512. SetRast(amb3d->graf->rast,amb3d->gcolor);
  513.  
  514. }
  515.  
  516. /***********************************
  517.  ** DISEGNO UN PIXEL NEL DISPLAY  **
  518.  ** BUFFER CHUNKY.          **
  519.  ***********************************
  520.  **** INPUT :              **
  521.  ** amb3d -> valore >0 ritornato  **
  522.  **         dalla funzione d'ini- **
  523.  **         zializzazione.        **
  524.  ** buf -> puntatore a struttura  **
  525.  **       polytemp con dati       **
  526.  **       poligono.          **
  527.  **** OUTPUT:              **
  528.  ** nessuno .              **
  529.  ***********************************/
  530. void pixel( struct ambient3d *amb3d, struct polytemp *buf)
  531. {
  532. struct RastPort *rast;
  533. long int *tcol,c;
  534.  
  535. tcol=amb3d->graf->t_color;
  536. c=tcol[buf->color]+buf->shade;
  537. if (c==TRASP) return((void)0);
  538.  
  539. rast=amb3d->graf->rast;
  540.  
  541. SetAPen(rast,c);
  542. WritePixel(rast,buf->x1,buf->y1);
  543.  
  544. }
  545.  
  546. /***********************************
  547.  ** DISEGNO UNA RIGA NEL DISPLAY  **
  548.  ** BUFFER CHUNKY.          **
  549.  ***********************************
  550.  **** INPUT :              **
  551.  ** amb3d -> valore >0 ritornato  **
  552.  **         dalla funzione d'ini- **
  553.  **         zializzazione.        **
  554.  ** buf -> puntatore a struttura  **
  555.  **       polytemp con dati       **
  556.  **       poligono.          **
  557.  **** OUTPUT:              **
  558.  ** nessuno .              **
  559.  ***********************************/
  560. void line( struct ambient3d *amb3d, struct polytemp *buf)
  561. {
  562. struct RastPort *rast;
  563. long int *tcol,c;
  564.  
  565. tcol=amb3d->graf->t_color;
  566. c=tcol[buf->color]+buf->shade;
  567. if (c==TRASP) return((void)0);
  568.  
  569. rast=amb3d->graf->rast;
  570.  
  571. SetAPen(rast,c);
  572. Move(rast,buf->x1,buf->y1);
  573.  
  574. switch (buf->numpoints)
  575.     {
  576.         case (2):
  577.             Draw(rast,buf->x2,buf->y2);
  578.             break;
  579.         case (3):
  580.         case (4):
  581.             PolyDraw(rast,buf->numpoints+1,(short int *)buf);
  582.             break;
  583.     }
  584.  
  585. }
  586. /***********************************
  587.  ** DISEGNO UN TRIANGOLO CON O    **
  588.  ** SENZA BORDO NEL DISPLAY       **
  589.  ** BUFFER CHUNKY.          **
  590.  ***********************************
  591.  **** INPUT :              **
  592.  ** amb3d -> valore >0 ritornato  **
  593.  **         dalla funzione d'ini- **
  594.  **         zializzazione.        **
  595.  ** buf -> puntatore a struttura  **
  596.  **       polytemp con dati       **
  597.  **       poligono.          **
  598.  ** bordo-> =-1 senza bordo       **
  599.  **         >=0 colore bordo.     **
  600.  **** OUTPUT:              **
  601.  ** nessuno .              **
  602.  ***********************************/
  603. void drw_tg( struct ambient3d *amb3d, struct polytemp *buf, long int bordo)
  604. {
  605. struct RastPort *rast;
  606. long int *tcol,c;
  607.  
  608. tcol=amb3d->graf->t_color;
  609. c=tcol[buf->color]+buf->shade;
  610. if (c==TRASP) return((void)0);
  611.  
  612. rast=amb3d->graf->rast;
  613.  
  614. SetAPen(rast,c);
  615.  
  616. BNDRYOFF(rast)
  617. if (bordo>=NULL) SetOutlinePen(rast,bordo);
  618.  
  619. AreaMove(rast,buf->x1,buf->y1);
  620. AreaDraw(rast,buf->x2,buf->y2);
  621. AreaDraw(rast,buf->x3,buf->y3);
  622. AreaEnd(rast);
  623.  
  624. }
  625.  
  626. /***********************************
  627.  ** DISEGNO UN QUADRILATERO CON O **
  628.  ** SENZA BORDO NELLA RASTPORT    **
  629.  ** NASCOSTA.              **
  630.  ***********************************
  631.  **** INPUT :              **
  632.  ** amb3d-> valore >0 ritornato   **
  633.  **         dalla funzione d'ini- **
  634.  **         zializzazione.        **
  635.  ** buf -> puntatore a struttura  **
  636.  **       polytemp con dati       **
  637.  **       poligono.          **
  638.  ** bordo-> =-1 senza bordo       **
  639.  **         >=0 colore bordo.     **
  640.  **** OUTPUT:              **
  641.  ** nessuno .              **
  642.  ***********************************/
  643. void drw_qg( struct ambient3d *amb3d, struct polytemp *buf, long int bordo)
  644. {
  645. struct RastPort *rast;
  646. long int *tcol,c;
  647.  
  648. tcol=amb3d->graf->t_color;
  649. c=tcol[buf->color]+buf->shade;
  650. if (c==TRASP) return((void)0);
  651.  
  652. rast=amb3d->graf->rast;
  653.  
  654. SetAPen(rast,c);
  655.  
  656. BNDRYOFF(rast)
  657. if (bordo>=NULL) SetOutlinePen(rast,bordo);
  658.  
  659. AreaMove(rast,buf->x1,buf->y1);
  660. AreaDraw(rast,buf->x2,buf->y2);
  661. AreaDraw(rast,buf->x3,buf->y3);
  662. AreaDraw(rast,buf->x4,buf->y4);
  663. AreaEnd(rast);
  664.  
  665. }
  666.  
  667.